package com.example.gprcdemo;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.example.gprcdemo.helloworld.GreeterGrpc;
import com.example.gprcdemo.helloworld.HelloReply;
import com.example.gprcdemo.helloworld.HelloRequest;
import com.example.gprcdemo.helloworld.Reply;
import com.example.gprcdemo.helloworld.OtherRequest;
import com.google.protobuf.ByteString;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference;

import io.grpc.netty.NettyServerBuilder;
import io.grpc.stub.StreamObserver;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.ByteBufUtil;

/**
 * @Author : ZYB
 * @Date : on 2023/12/12 .
 * @Description : 用来启动服务端
 */
public class GRPCServer {
    private final String TAG = GRPCServer.class.toString();

    private final int port = 9005;
    private Context context;

    public GRPCServer(Context context) {
        this.context = context;
       // start();

    }

    // 使用广播的方法发送数据更新ui
    private void sendInfo(String info) {
      /*  Intent intent = new Intent("main.info");
        intent.putExtra("info", info);
        context.sendBroadcast(intent);*/
        Log.d(TAG, info);

    }

    public void start() {
        try {
            NettyServerBuilder.forPort(port)
                    .addService(new GRPCServiceImpl(context))
                    .build()
                    .start();
            Log.d(TAG, "服务端启动");
            sendInfo("服务端启动");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private class GRPCServiceImpl extends GreeterGrpc.GreeterImplBase {


        private Context context;

        public GRPCServiceImpl(Context context) {
            this.context = context;
        }

        @Override
        public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
            responseObserver.onNext(sayHello(request));
            responseObserver.onCompleted();
        }

        private HelloReply sayHello(HelloRequest request) {
            int newcode = 200;
            String msg = "success " + request.getName();
            if (request.getName().equals("200")) {
                newcode = 400;
                msg = "fail  " + request.getName();
                ;
            }
            return HelloReply.newBuilder()
                    .setMessage(newcode+msg)
                    .build();
        }
//一元模式
        @Override
        public void simpleHello(OtherRequest request, StreamObserver<Reply> responseObserver) {
            Log.d(TAG, "服务端调用simpleHello.");
            String info = "[客户端->服务端]" + request.getReqInfo();
            sendInfo(info);
            responseObserver.onNext(Reply.newBuilder().setRepInfo("simpleHello").build());
            responseObserver.onCompleted();
            super.simpleHello(request, responseObserver);
        }
//客户端流模式
        @Override
        public StreamObserver<OtherRequest> clientStream(StreamObserver<Reply> responseObserver) {
            StreamObserver<OtherRequest> streamObserver = new StreamObserver<OtherRequest>() {
                @Override
                public void onNext(OtherRequest value) {
                    Log.d(TAG, "clientStream onNext.");
                    String info = "[服务端->客户端]" + value.getReqInfo();
                    sendInfo(info);
                }

                @Override
                public void onError(Throwable t) {
                    Log.d(TAG, "clientStream onError.");
                }

                @Override
                public void onCompleted() {
                    Log.d(TAG, "clientStream onCompleted.");
                    // 接收完所有消息后给客户端发送消息
                    responseObserver.onNext(Reply.newBuilder().setRepInfo("clientStream").build());
                    responseObserver.onCompleted();
                }
            };
            return streamObserver;
        }
        // 服务端流模式
        @Override
        public void serverStream(OtherRequest request, StreamObserver<Reply> responseObserver) {
            String info = "[客户端->服务端]" + request.getReqInfo();
            sendInfo(info);
            responseObserver.onNext(Reply.newBuilder().setRepInfo("serverStream1").build());
            responseObserver.onNext(Reply.newBuilder().setRepInfo("serverStream2").build());
            super.serverStream(request, responseObserver);
            responseObserver.onCompleted();
        }
        // 双向流模式
        @Override
        public StreamObserver<OtherRequest> bothFlowStream(StreamObserver<Reply> responseObserver) {
            StreamObserver<OtherRequest> streamObserver = new StreamObserver<OtherRequest>() {
                @Override
                public void onNext(OtherRequest value) {
                    Log.d(TAG, "bothFlowStream onNext.");
                    String info = "[客户端->服务端]" + value.getReqInfo();
                    sendInfo(info);
                }

                @Override
                public void onError(Throwable t) {
                    Log.d(TAG, "bothFlowStream onError.");
                }

                @Override
                public void onCompleted() {
                    Log.d(TAG, "bothFlowStream onCompleted.");
                    responseObserver.onNext(Reply.newBuilder().setRepInfo("bothFlowStream1").build());
                    responseObserver.onNext(Reply.newBuilder().setRepInfo("bothFlowStream2").build());
                    responseObserver.onCompleted();
                }
            };
            return streamObserver;
        }

        @Override
        public void serverDownloadFile(OtherRequest request, StreamObserver<Reply> responseObserver) {
            String filePath = "/storage/emulated/0/DCIM/Camera/a3.jpg";
            if ("a3".equals(request.getReqInfo())){
                  filePath = "/storage/emulated/0/DCIM/Camera/a3.jpg";
            }else {
                  filePath = "/storage/emulated/0/DCIM/Camera/a2.jpg";
            }
           // Path filePath = Paths.get(URI.create(filePath));
            try (FileInputStream inputStream = new FileInputStream(new File(filePath))) {
                long allLength = new File(filePath).length();
                long progress = 0;
                byte[] buffer = new byte[4096]; // 4KB buffer
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    byte[] chunk = Arrays.copyOf(buffer, bytesRead);
                    ByteString byteString = ByteString.copyFrom(chunk);
                    progress +=bytesRead;
                    Log.i(TAG, "onNext长度: "+progress);
                    responseObserver.onNext(Reply.newBuilder().setContent(byteString).setAllSize(allLength).setLoadProgress(progress).setRepInfo(request.getReqInfo()).build());
                }
                responseObserver.onCompleted();
            } catch (IOException e) {
                responseObserver.onError(e);
            }


          /*  byte[] fileBytes = new byte[0];
            try {
                FileInputStream inputStream = new FileInputStream(filePath);
                fileBytes = new byte[inputStream.available()];
                inputStream.read(fileBytes);
                inputStream.close();
                System.out.println("File read into byte array successfully.");
            } catch (IOException e) {
                System.out.println("Error reading file: " + e.getMessage());
            }
           byte[] decodedBytes = new String(fileBytes, StandardCharsets.ISO_8859_1).getBytes(StandardCharsets.UTF_8);
            ByteString byteString = ByteString.copyFrom(decodedBytes);
                responseObserver.onNext(Reply.newBuilder().setRepInfoBytes(byteString).setRepInfo("").build());
                responseObserver.onCompleted();*/
        }
    }

}